package com.example.administrator.common.ui;

/** @author LQW
 * Created by Administrator on 2017/11/28.
 */

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;

/**
 * 主界面底部导航栏
 */
public class TabBar extends LinearLayout {

    private String[] mTabNames;

    private int[] mTabIconsNormal;
    private int[] mTabIconsSelected;

    /** 选项卡字体和图标的颜色：普通状态 */
    private int mTabColorNormal = Color.GRAY;

    /** 选项卡字体和图标的颜色：选中状态 */
    private int mTabColorSelected = Color.WHITE;

    /** 五个选项卡 */
    private TabItem[] mTabs;

    /** 当前选中的选项卡 */
    private TabItem mCurrentTab;

    /** 选项卡图标的宽 */
    private int mIconWidth;
    /** 选项卡图标的高 */
    private int mIconHeight;

    public TabBar(Context context) {
        super(context);
        init();
    }

    private void init() {
    }

    private int dp2px(int dp) {
        return (int) (getContext().getResources().getDisplayMetrics().density * dp
                + 0.5f);
    }

    public TabBar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    /**
     * 设置选项卡未读条数
     * @param position 要设置的选项卡
     * @param unreadCount
     */
    public void setTabUnreadCount(int position, int unreadCount) {
        try {
            mTabs[position].setUnreadCount(unreadCount);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 显示或隐藏选项卡上的红点（红点表示有信息更新）
     *
     * @param position 要设置的选项卡
     * @param visible true为显示
     */
    public void setRedDotVisible(int position, boolean visible) {
        try {
            mTabs[position].setRedDotVisible(visible);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    /** 设置选项卡的透明度 */
    public void updateTabAlpha(int position, float alpha) {
        try {
            mTabs[position].updateTabAlpha(alpha);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public void setTabColorNormal(int tabColorNormal) {
        this.mTabColorNormal = tabColorNormal;
    }

    public void setTabColorSelected(int tabColorSelected) {
        this.mTabColorSelected = tabColorSelected;
    }

    public void setTabSelectedColor(int color) {
        setTabColorSelected(color);
        if (mCurrentTab != null) {
            for (int i = 0; i < mTabs.length; i++) {
                TabItem tab = mTabs[i];
                tab.setTabSelectedColor(color);
            }
        }
    }

    public void setTabNormalColor(int color) {
        setTabColorNormal(color);
        if (mCurrentTab != null) {
            for (int i = 0; i < mTabs.length; i++) {
                TabItem tab = mTabs[i];
                tab.setTabNormalColor(color);
            }
        }
    }

    /** 选项卡中图片与文字的垂直间距 */
    int paddingBetweenTextAndIcon = dp2px(0);

    /** 设置图标和文本之间的间距 */
    public void setPaddingBetweenTextAndIcon(int padding) {
        this.paddingBetweenTextAndIcon = padding;
        if (mTabs != null) {
            for (int i = 0; i < mTabs.length; i++) {
                mTabs[i].setPaddingBetweenTextAndIcon(paddingBetweenTextAndIcon);
            }
            invalidate();
        }
    }

    public void setIconSize(int iconWidth, int iconHeight) {
        this.mIconWidth  = iconWidth;
        this.mIconHeight = iconHeight;
        if (mTabs != null) {
            for (int i = 0; i < mTabs.length; i++) {
                mTabs[i].setIconSize(iconWidth, iconHeight);
            }
        }
    }

    /** 选项卡切换监听 */
    public interface OnTabSelectedListener {
        public void onTabSelected(int position);
    }

    private OnTabSelectedListener mOnTabSelectedListener;

    public void setOnTabSelectedListener(OnTabSelectedListener onTabSelectedListener) {
        this.mOnTabSelectedListener = onTabSelectedListener;
    }

    OnClickListener mOnTabClickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            int position = (int) v.getTag();
            setTabSelected(position);

            // 选项卡切换了, 作回调
            if (mOnTabSelectedListener != null) {
                mOnTabSelectedListener.onTabSelected(position);
            }
        }
    };

    /**
     * 设置选项卡显示的数据和图标
     *
     * @param titles 选项卡显示的文本
     * @param iconsNormal  选项卡默认状态下显示的图标
     * @param iconsSelected 选项卡选中状态下显示的图标
     */
    public void setTabDatas(String[] titles, int[] iconsNormal, int[] iconsSelected) {
        this.mTabNames = titles;
        this.mTabIconsNormal = iconsNormal;
        this.mTabIconsSelected = iconsSelected;

        removeAllViews();

        mTabs = new TabItem[titles.length];
        int padding = dp2px(5);		// 5dp

        LayoutParams param = new LayoutParams(0,
                LayoutParams.MATCH_PARENT);
        param.weight = 1;		// 使用权重，表示五个选项卡会平分屏幕的宽度

        for (int i = 0; i < mTabs.length; i++) {
            TabItem tab = new TabItem(getContext());
            mTabs[i] = tab;

            // 设置选项卡的标题和图片
            int iconSelected = mTabIconsSelected != null ? mTabIconsSelected[i] : 0;
            tab.setTextAndIcon(titles[i], mTabIconsNormal[i], iconSelected);

            tab.setTabNormalColor(mTabColorNormal);
            tab.setTabSelectedColor(mTabColorSelected);

            tab.setOnClickListener(mOnTabClickListener);

            if (paddingBetweenTextAndIcon != 0)
                tab.setPaddingBetweenTextAndIcon(paddingBetweenTextAndIcon);

            if (mIconWidth != 0)
                tab.setIconSize(mIconWidth, mIconHeight);

            tab.setTag(i);
            tab.setPadding(0, padding, 0, padding);

            addView(tab, param);
        }

        // 默认选中的是第一个选项卡
        mCurrentTab = mTabs[0];
        mCurrentTab.setTabSelected(true);  		// 选中，选项卡会高亮显示
    }

    public void setTabDatas(String[] titles, int[] iconsNormal) {
        setTabDatas(titles, iconsNormal, null);
    }

    /**
     * 选中某一个选项卡
     *
     * @param position 要选中的位置
     */
    public void setTabSelected(int position) {
        System.out.println("-----------position: " + position);
        if (mTabNames != null && position >= 0 && position < mTabNames.length) {
            // 当前选中的取消高亮
            mCurrentTab.setTabSelected(false);

            // 记录新的选中的选项卡
            mCurrentTab = mTabs[position];

            // 新点击的选项卡设为高亮
            mCurrentTab.setTabSelected(true);
        }
    }

    /**
     * 主界面底部选项卡指示器控件. <br/>
     * （1）选项卡显示的内容需包括图标和文字内容。<br/>
     * （2）可以传两张图片，也可以传一张图片，如果传一张图片，选中的的高亮效果会通过着色实现<br/>
     * （3）传一张图片时，可以实现类似微信的滑动时的选项卡渐变效果<br/>
     *
     * @author LQW
     */
    public static class TabItem extends View {

        /** tab显示的文本 */
        private String mTabText = "标题";

        /** 选项卡图标: 普通状态。也可以只使用一张图标，选中时会对它进行着色 */
        private Bitmap mTabIconNormal;
        /** 选项卡图标: 选中状态。也可以只使用一张图标，选中时会对它进行着色 */
        private Bitmap mTabIconSelected;

        /** 选项卡字体和图标的颜色：普通状态 */
        private int mTabColorNormal = Color.GRAY;

        /** 选项卡字体和图标的颜色：选中状态 */
        private int mTabColorSelected = Color.WHITE;

        /** 选项卡字体大小: 默认为12sp */
        private int mTabTextSize = dp2px(12);

        /** 选项卡中图标的宽 */
        private int mIconWidth = dp2px(25);
        /** 选项卡中图标的高 */
        private int mIconHeight = dp2px(25);
        /** 选项卡中图片与文字的垂直间距 */
        int paddingBetweenTextAndIcon = dp2px(0);

        /** 滑动时图标的透明度 */
        private float mAlphaPercent;

        /** 渐变的bitmap对象 */
        private Bitmap mGradientBitmap;

        /** 绘制图标的画笔 */
        private Paint mIconPaint;
        /** 绘制文本的画笔 */
        private Paint mTextPaint = new Paint();

        /** 图标的绘制区域 */
        private Rect mIconRect = new Rect();
        /** 文字的绘制区域 */
        private Rect mTextBound = new Rect();

        public TabItem(Context context) {
            super(context);
            init();
        }

        public TabItem(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }

        public void init() {
            mTextPaint.setAntiAlias(true);
            mTextPaint.setTextSize(mTabTextSize);
            mTextPaint.setColor(mTabColorNormal);
            mTextPaint.getTextBounds(mTabText, 0, mTabText.length(), mTextBound);
            mRedDotPaint.setAntiAlias(true); 	// 去锯齿

            mUnreadCountPaint.setAntiAlias(true); // 去锯齿
            mUnreadCountPaint.setTextSize(mTabTextSize);
            mUnreadCountPaint.setTextAlign(Paint.Align.CENTER); // 居中显示

            getUnreadCountTextHeight();
        }

        /** 设置选项卡选中时字体和图标的颜色 */
        public void setTabSelectedColor(int color) {
            this.mTabColorSelected = color;
            invalidate();
        }

        /** 设置选项卡非选中状态下字体和图标的颜色 */
        public void setTabNormalColor(int color) {
            this.mTabColorNormal = color;
            invalidate();
        }

        /** 获取未读条数字体显示高度 */
        public void getUnreadCountTextHeight() {
            Rect unreadCountRect = new Rect();
            mUnreadCountPaint.getTextBounds("1", 0, 1, unreadCountRect);
            mUnreadCountTextHeight = unreadCountRect.height();
        }

        /**
         * 测量控件，初始化图标的绘制区域
         */
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            // 图标宽高是一样的，取两者的较小值
            initTabDrawArea();
        }

        /**
         * 根据图片的宽高，初始化选项卡图标相对于选项卡本身的绘制区域,保存到变量mIconRect中
         */
        private void initTabDrawArea() {
            int left = getMeasuredWidth() / 2 - mIconWidth / 2;
            int top = getMeasuredHeight() / 2 - (mTextBound.height() + mIconHeight) / 2;

            mIconRect.left = left;
            mIconRect.top = top;
            mIconRect.right = left + mIconWidth;
            mIconRect.bottom = top + mIconHeight;
        }

        /**
         * 设置选项卡中图标的宽和高
         * @param iconWidth
         */
        public void setIconSize(int iconWidth, int iconHeight) {
            this.mIconWidth = iconWidth;
            this.mIconHeight = iconHeight;
            initTabDrawArea();
            invalidate();
        }

        @Override
        protected void onDraw(Canvas canvas) {
            // 绘制红点
            drawRedDot(canvas, mShowRedDot);

            // 绘制未读取条数
            drawUnreadCount(canvas, mUnreadCount);

            // 绘制tab原文本
            drawText(canvas, mTabColorNormal, 255);

            // 绘制渐变色的文本
            int alpha = (int) Math.ceil(255 * mAlphaPercent);
            drawText(canvas, mTabColorSelected, alpha);
            System.out.println("-------------mTabColorSelected: " + mTabColorSelected);

            if (mTabIconSelected == null) {	//只使用一张图片实现选项卡的普通和高亮两种状态
                // 绘制tab图标
                canvas.drawBitmap(mTabIconNormal, null, mIconRect, null);

                // 内存去准备mBitmap , setAlpha , 纯色 ，xfermode
                mGradientBitmap = createGradientBitmap(alpha, mTabColorSelected);

                // 绘制渐变色的图标
                canvas.drawBitmap(mGradientBitmap, 0, 0, null);

            } else {	//使用两张图片实现选项卡的普通和高亮两种状态
                if (alpha == 0) {
                    canvas.drawBitmap(mTabIconNormal, null, mIconRect, null);
                } else {
                    canvas.drawBitmap(mTabIconSelected, null, mIconRect, null);
                }
            }
        }

        private int dp2px(int dp) {
            return (int) (dp * getContext().getResources().getDisplayMetrics().density);
        }

        /**
         * 绘制文本
         *
         * @param canvas
         * @param alpha
         */
        private void drawText(Canvas canvas, int color, int alpha) {
            mTextPaint.setColor(color);
            mTextPaint.setAlpha(alpha);
            int x = (getMeasuredWidth()  - mTextBound.width()) / 2;
            int y = mIconRect.bottom + mTextBound.height() + paddingBetweenTextAndIcon;
            canvas.drawText(mTabText, x, y, mTextPaint);
        }

        /** 设置图标和文本之间的间距 */
        public void setPaddingBetweenTextAndIcon(int padding) {
            this.paddingBetweenTextAndIcon = padding;
        }

        /**
         * 在内存中绘制可变色的Icon
         * @param alpha 透明度
         * @param gradientColor 渐变色
         * @return
         */
        private Bitmap createGradientBitmap(int alpha, int gradientColor) {
            Canvas canvas = null;
            if (mGradientBitmap != null) {
                mGradientBitmap.recycle();
            }

            mGradientBitmap = Bitmap.createBitmap(getMeasuredWidth(),
                    getMeasuredHeight(), Bitmap.Config.ARGB_8888);
            canvas = new Canvas(mGradientBitmap);
            mIconPaint = new Paint();
            mIconPaint.setColor(gradientColor);
            mIconPaint.setAntiAlias(true); // 去矩齿
            mIconPaint.setDither(true);
            mIconPaint.setAlpha(alpha); // 透明度
            canvas.drawRect(mIconRect, mIconPaint); // 画了一个矩形

            mIconPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));

            mIconPaint.setAlpha(255);
            // 画了图标，图标与短形是重叠的，通过setXfermode()决定出来的效果
            canvas.drawBitmap(mTabIconNormal, null, mIconRect, mIconPaint);
            return mGradientBitmap;
        }

        /**
         * 更新Tab显示的透明度
         * @param alphaPercent 透明度 0 到 1
         */
        public void updateTabAlpha(float alphaPercent) {
            // 如果使用了两张图片实现普通和高亮的效果，
            // 则禁用颜色渐变的功能；
            if (mTabIconSelected != null) {
                if (alphaPercent != 0 && alphaPercent != 1)
                    return;
            }

            this.mAlphaPercent = alphaPercent;
            invalidate();
        }

        /**
         * 设置Tab的选中状态
         *
         * @param selected true时显示为高亮, false为正常的显示状态
         */
        public void setTabSelected(boolean selected) {
            updateTabAlpha(selected ? 1 : 0);
        }

        /**
         * 设置要绘制的文本和图标。</br>
         * 可以只设置一张默认的图标，控件会使用填充色对该图标进行染色得到选中时的高亮图标，
         * 可以通过setTextAndIcons方法同时指定普通状态和选中状态的两个图标.
         *
         * @param text tab显示的文本
         * @param icon tab显示的图标
         */
        public void setTextAndIcon(String text, int icon) {
            this.mTabText = text;
            this.mTabIconNormal = BitmapFactory.decodeResource(getResources(), icon);
            mTextPaint.getTextBounds(mTabText, 0, mTabText.length(), mTextBound);
            invalidate();
        }

        /**
         * 设置要绘制的文本和图标。</br>
         *
         * @param text tab显示的文本
         * @param icon tab显示的图标
         * @param iconSelected tab选中时显示的图标
         */
        public void setTextAndIcon(String text, int icon, int iconSelected) {
            this.mTabText = text;
            this.mTabIconNormal = BitmapFactory.decodeResource(getResources(), icon);
            if (iconSelected > 0) {
                this.mTabIconSelected = BitmapFactory.decodeResource(getResources(), iconSelected);
            }
            mTextPaint.getTextBounds(mTabText, 0, mTabText.length(), mTextBound);
            invalidate();
        }

        /** 是否显示红点 */
        private boolean mShowRedDot = false;

        private Paint mRedDotPaint = new Paint();

        /**
         * 绘制红点提示，传false还未隐藏红点(以后可拓展)
         *
         * @param canvas
         * @param showRedDot 传true表示绘制红点，传false会清除之前绘制的红点
         */
        private void drawRedDot(Canvas canvas, boolean showRedDot) {
            mRedDotPaint.setColor(showRedDot ? Color.RED : Color.TRANSPARENT);
            canvas.drawCircle(mIconRect.right + dp2px(3), mIconRect.top + dp2px(5), dp2px(5), mRedDotPaint);
        }

        /**
         * 显示红点
         *
         * @param visible true表示显示
         */
        private void setRedDotVisible(boolean visible) {
            mShowRedDot = visible;
            invalidate();
        }

        /**
         * 显示选项卡上的红点，表示有新的消息
         */
        public void showRedDot() {
            mShowRedDot = true;
            invalidate();
        }

        /**
         * 隐藏选项卡上的红点
         */
        public void hideRedDot() {
            mShowRedDot = false;
            invalidate();
        }

        private int mUnreadCount;

        public void setUnreadCount(int unreadCount) {
            this.mUnreadCount = unreadCount;
            invalidate();
        }

        private Paint mUnreadCountPaint = new Paint();
        private int mUnreadCountTextHeight;

        public void drawUnreadCount(Canvas canvas, int unreadCount) {
            boolean showUnreadCount = unreadCount > 0;
            mUnreadCountPaint.setColor(showUnreadCount? Color.WHITE : Color.TRANSPARENT);
            mRedDotPaint.setColor(showUnreadCount ? Color.RED : Color.TRANSPARENT);

            // 未读条数超过两位数时显示三个点...
            String text = unreadCount < 100 ? String.valueOf(unreadCount) : "...";
            int left = mIconRect.right + dp2px(8);
            int top = mIconRect.top + dp2px(9);

            canvas.drawCircle(left, top, dp2px(9), mRedDotPaint);
            canvas.drawText(text, left,  top +  mUnreadCountTextHeight / 2, mUnreadCountPaint);
        }
    }
}

